float4x4 gWorld : WORLD;
float4x4 gViewProjection : VIEWPROJECTION;
float gTime : TIME;

// The direction of the light
float4 gLightDir : DIRECTION
< string Object = "DirectionalLight"; >
= { 0, 0, -3, 0};

// The textures
Texture2D gDiffuseTexture;

sampler2D gDiffuseSampler = sampler_state 
{
    Texture = <gDiffuseTexture>;
	Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

Texture2D gNormalTexture;

sampler2D gNormalSampler = sampler_state 
{
    Texture = <gNormalTexture>;
	Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

Texture2D gSpecularTexture;

sampler2D gSpecularSampler = sampler_state 
{
    Texture = <gSpecularTexture>;
	Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};

Texture2D gEmissiveTexture;

sampler2D gEmissiveSampler = sampler_state 
{
    Texture = <gEmissiveTexture>;
	Filter = MIN_MAG_MIP_LINEAR;
    AddressU = Wrap;
    AddressV = Wrap;
};


struct VERTEX_INPUT
{
    float3 pos		: POSITION0;
	float3 norm		: NORMAL0;
	float2 uv 		: TEXCOORD0;
	float3 tangent	: TANGENT;
};

struct PIXEL_INPUT
{
    float4 pos		: SV_POSITION;
	float3 norm		: TEXCOORD0;
	float2 uv		: TEXCOORD1;
	float3 light	: TEXCOORD2;
};

PIXEL_INPUT VertShader(VERTEX_INPUT input)
{
	PIXEL_INPUT output;

	// Pass in the normals
	float4 worldNorm = float4(input.norm, 0.0f);
	output.norm = normalize(mul(worldNorm, gWorld));

	
	// Pass in the positions
	float4x4 worldViewProj = mul(gWorld, gViewProjection);
	output.pos = mul(float4(input.pos, 1.0f), worldViewProj);

	// Pass in the texture coordinates
	output.uv = input.uv;
	
	// Pass in the tangent space matrix
	float3x3 TBN;
	TBN[0] = input.tangent;
	TBN[2] = input.norm;
	
	float3 binorm = cross(TBN[2], TBN[0]);
	
	TBN[1] = binorm;
	
    float3x3 TBN_Transpose = transpose(TBN);
	
	// Calculate the light and move it across
	float3 lightVec = gLightDir - output.pos;
	
	lightVec = mul(-lightVec, TBN);
	
	lightVec = normalize(lightVec);
	
	output.light = lightVec;
	
	
	// Send the struct to the pixel shader
	return output; 
}

float4 FragmentShader(PIXEL_INPUT input) : COLOR
{
	//////////////////
	// Just Texture //
	//////////////////
	//return tex2D(gDiffuseSampler, input.uv);

	////////////////////////////
	// Diffuse and normal map //
	////////////////////////////
	
	// The final color
	float4 finalColor;
	
	// Get the light direction
	float3 LDir = input.light;
	
	// Get the diffuse color
	float4 diffuseColor = tex2D(gDiffuseSampler, input.uv);
	
	// Get the normal map
	float3 normalMap = tex2D(gNormalSampler, input.uv);
	
	// Get the emissive color
	float3 emissiveColor = tex2D(gEmissiveSampler, input.uv);
	
	// Convert the normal map into the proper space
	normalMap = (normalMap * 2.0f) - 1.0f;
	

    // Calculate the amount of light on this pixel
    float intensity = saturate(dot(normalMap, LDir));

    // Determine the final diffuse color
    //finalColor = saturate(float4(0.75f, 0.75f, 0.75f, 1.0f) * intensity);

    // Combine the final bump light color with the texture color.
    //finalColor = (finalColor * diffuseColor) + tex2D(gEmissiveSampler, input.uv);;
	
	return intensity * diffuseColor + tex2D(gEmissiveSampler, input.uv);
}

technique myTechnique
{
    pass FirstPass
    {
        vertexShader = compile vs_3_0 VertShader();
        pixelShader  = compile ps_3_0 FragmentShader();
		ShadeMode = GOURAUD;
        FillMode = SOLID;
        CullMode = CCW;
    }
}